module anem_mongo_mod

  use iso_c_binding
  use mongof_common_mod
  use datetime
  use string
  use container
  use flogger
  use params_mod
  use data_translators_utils_mod
  use anem_mod

  implicit none

  private

  public anem_mongo_write

  interface
    integer function anem_mongoc_insert_platform(cid, name, lon, lat, alt) result(res) bind(c, name='anem_mongoc_insert_platform')
      use iso_c_binding
      integer(c_int), intent(in) :: cid
      character(c_char), intent(in) :: name
      real(c_float), intent(in) :: lon
      real(c_float), intent(in) :: lat
      real(c_float), intent(in) :: alt
    end function anem_mongoc_insert_platform

    integer function anem_mongoc_insert_record(cid, name, timestamp, h, ws, wd) result(res) bind(c, name='anem_mongoc_insert_record')
      use iso_c_binding
      integer(c_int), intent(in) :: cid
      character(c_char), intent(in) :: name
      real(c_double), intent(in) :: timestamp
      real(c_float), intent(in) :: h
      real(c_float), intent(in) :: ws
      real(c_float), intent(in) :: wd
    end function anem_mongoc_insert_record
  end interface

contains

  subroutine anem_mongo_write(mongo_uri, mongo_db, mongo_col, towers, records)

    character(*), intent(in) :: mongo_uri
    character(*), intent(in) :: mongo_db
    character(*), intent(in) :: mongo_col
    type(hash_table_type), intent(in) :: towers
    type(linked_list_type), intent(in) :: records

    integer(c_int) cid_tower, cid_record
    character(10) sid
    type(linked_list_iterator_type) it

    call mongoc_init()

    call handle_mongo_error(mongoc_connect('mongodb://' // trim(mongo_uri) // char(0), trim(mongo_db) // char(0), &
      trim(mongo_col) // '_towers' // char(0), cid_tower), __FILE__, __LINE__)

    call handle_mongo_error(mongoc_connect('mongodb://' // trim(mongo_uri) // char(0), trim(mongo_db) // char(0), &
      trim(mongo_col) // '_records' // char(0), cid_record), __FILE__, __LINE__)

    call handle_mongo_error(mongoc_create_platform_index(cid_tower), __FILE__, __LINE__)
    call handle_mongo_error(mongoc_create_record_index(cid_record), __FILE__, __LINE__)

    call log_notice('Inserting ' // to_str(records%size) // ' records ...')
    it = linked_list_iterator(records)
    do while (.not. it%ended())
      select type (record => it%value)
      type is (anem_record_type)
        sid = trim(record%tower%name) // char(0)
        call handle_mongo_error(anem_mongoc_insert_platform(cid_tower, sid, &
          record%tower%lon, record%tower%lat, record%tower%z), __FILE__, __LINE__)
        call handle_mongo_error(anem_mongoc_insert_record(cid_record, sid, &
          record%time%timestamp(), record%h, record%ws_avg, record%wd_avg), __FILE__, __LINE__)
      end select
      call it%next()
    end do

    call mongoc_final()

  end subroutine anem_mongo_write

end module anem_mongo_mod
